///////////////////////////////////////////////////////////
///////////////// Have an itch? Scratch it! ///////////////
///////////////////////// SCRATCH /////////////////////////
/////////////////////  A MUD  Server   ////////////////////
///////////////////// By: Jared Devall ////////////////////
/////////////////////      Thanks:     ////////////////////
/////////////////////  DIKU/Merc/ROM   ////////////////////
///////////////////// Aetas/Deus Gang  ////////////////////
/////////////////////       Beej       ////////////////////
///////////////////////////////////////////////////////////

#include "editHandlers.h"
#include "avatar.h"
#include "world.h"
#include "stringutil.h"
#include "commandTable.h"
#include "split.h"
#include <iostream>
#include <cstring>
#include <list>

using namespace std;

EditAvatarHandler::EditAvatarHandler( ) {
	_edit = NULL;
}

EditAvatarHandler::EditAvatarHandler( Avatar * avatar, const string &name ) {
	string buf;
	_edit = new Avatar;
	_edit->Set( "name", name );
	if ( !_edit->Load() ) {
		delete _edit;
		_edit = NULL;
		avatar->Send( "That user does not exist.\n\r" );
    	return;
    }
    
    _name = _edit->Get( "name" );
	buf << "You are now editing [{b" << _edit->Get( "name" ) << "{x]\n\r";
	avatar->Send( buf );
}

void EditAvatarHandler::Enter( Avatar * avatar ) {	
	avatar->Send( "================================\n\r" );
	avatar->Send( "===      {WAvatar Editor{x       ===\n\r" );
	avatar->Send( "=== #help - More Information ===\n\r" );
	avatar->Send( "=== #quit - Exits Editor     ===\n\r" );
	avatar->Send( "================================\n\r" );	
}

void EditAvatarHandler::Exit( Avatar * avatar ) {
	delete this;
	return;
}


void EditAvatarHandler::Handle( Avatar * avatar, const string &input) {
	string checked;
	string option;
	string change;
	string buf;
	bool command = false;
	
	if ( input.empty () )
		return;
	
	checked = input;
	// Check to see if they're trying to 	
	for ( string::const_iterator cChar = input.begin(); cChar != input.end(); ++cChar ) {
		if ( (*cChar) == '/' && cChar == input.begin() ) {
			option = input.substr( 1, input.length() );
			if ( !strstr( input.c_str(), "quit" )  )// FIXEME: do not quit while editing
				CommandTable::Instance().Execute( avatar, option );
			return;
		} else if ( (*cChar) == '#' && cChar == input.begin() ) {
			command = true;
			option = input.substr( 1, input.length() );
			checked = option;
			option.erase();
			break;
		} else if ( ( (*cChar) == '\n' || (*cChar) == '\r' ) && cChar == input.begin() ) {
			checked.erase();
			break;
		}
	 }
	
	split( checked, option, change ); 
	
	if ( !strcasecmp( option, "quit" ) && command == true ) {
		Avatar * test;
		if ( _edit ) {
			_edit->Save();
			if ( ( test = World::Instance().FindAvatar( _name ) )!= NULL ) {				
				if ( str_cmp( _edit->Get( "name" ), test->Get( "name" ) ) )
					test->Set( "name", _name );
				test->Load();
			}				
			_edit = NULL;
		} else {
			avatar->ExitHandler();		
		}
		return;
	} else if ( ( !strcasecmp( option, "commands" ) || !strcasecmp( option, "help" ) ) ) {
		string buf;
		if ( !_edit ) {
			buf << "Enter the name of the user you wish to edit.\n\r";
		} else {
 	   	buf << "|------------------------------ Help ---------------------------------|\n\r";
 	   	buf << "| #commands          This help file.                                  |\n\r";
 	   	buf << "| #show              Shows what you are editing.                      |\n\r";
 	   	buf << "| #quit              Quits the Editor and saves the player            |\n\r";
 	   	buf << "| #save              Save your current progress.                      |\n\r";
 	   	buf << "| #delete            Delete the help file you're editing.             |\n\r";
 	   	buf << "|                                                                     |\n\r";
 	   	buf << "| Editing Commands                                                    |\n\r";
    		buf << "| name     <name>    Changes the users name.                          |\n\r";
 	   	buf << "| group    <group>   Changes the users group.                         |\n\r";
			buf << "| password <pass>    Changes the users password.                      |\n\r";
 	  	 buf << "| title    <title>   Changes the users title.                         |\n\r";
 	   	buf << "| reply    <reply>   Changes who the user will reply to.              |\n\r";
 	   	buf << "|                                                                     |\n\r";
 	   	buf << "| {R*{x Commands preceded by a {B/{x will be executed as regular commands.    |\n\r";
 	   	buf << "|---------------------------------------------------------------------|\n\r\n\r";
 	   }
 	   avatar->Send( buf );
 	   return;
	}
	
		if ( checked.empty() || ( !strcasecmp( option, "show" ) && command == true ) ) {
			if ( _edit ) {
				buf << "[name: " << _edit->Get( "name" ) << "]\n\r";
				buf << "[group: " << _edit->Get("group") << "]\n\r";
				buf << "[password: (hidden)]\n\r";
				buf << "[title: " << _edit->Get("title") << "]\n\r";
				buf << "[reply: " << _edit->Get("reply") << "]\n\r";
				buf << "[login: " << _edit->Get("login") << "]\n\r";
			} else {
				buf << "You are not currently editing anything.\n\r";
			}
			avatar->Send( buf );
			return;
		} else if ( _edit ) {			
			if ( !strcasecmp( option, "name" ) ) {
				string oldName = _edit->Get( "name" );			
				Avatar * test = new Avatar;
				test->Set( "name", change );
				
				if ( strcasecmp( change, oldName ) && test->Load() ) {
					avatar->Send( "That name exists already.\n\r" );
					delete test;
					return;
				}

				_edit->Set( "name", change );
				if ( strcasecmp( change, oldName ) )
					_edit->Create();
				_edit->Save(); 
				if ( strcasecmp( change, oldName ) ) {
					_edit->Set( "name", oldName );
					_edit->Delete();
					_edit->Set( "name", change );
				}
				_edit->Load();
				if ( ( test = World::Instance().FindAvatar( _name ) )!= NULL ) {				
						test->Set( "name", _edit->Get( "name" ) );
						test->Load();
				}
				avatar->Send( "Name updated.\n\r" );
				return;
			} else if ( !strcasecmp( option, "group" ) ) {
				_edit->Set( "group", change );
				avatar->Send( "Group updated.\n\r" );
				return;
			} else if ( !strcasecmp( option, "title" ) ) {
				_edit->Set( "title", change );
				avatar->Send( "Title updated.\n\r" );
				return;
			} else if ( !strcasecmp( option, "password" ) ) {
				_edit->Set( "password", _edit->EncryptPassword( change ) );
				avatar->Send( "Password changed.\n\r" );
				return;
			} else if ( !strcasecmp( option, "reply" ) ) {				
				_edit->Set( "reply", change );
				avatar->Send( "Reply updated.\n\r" );				
				return;
			} else if ( ( !strcasecmp( option, "save" ) && command == true ) ) {
				_edit->Save();
				Avatar * test;	
				if ( ( test = World::Instance().FindAvatar( _name ) ) != NULL ) {				
						test->Set( "name", _edit->Get( "name" ) );
						test->Load();
				}
					
				avatar->Send( "Player saved.\n\r" );
				return;				
			} else if ( ( !strcasecmp( option, "delete" ) && command == true ) ) {
				string buf;
				buf << _edit->Get( "name" ) << " has been deleted.\n\r";
				_edit->Delete();
  	  		delete _edit;
  	  		_edit = NULL;
  	  		avatar->Send( buf );
  	  		return;
  	  	}				
		} else if ( !_edit ) {			
			_edit = new Avatar;
			_edit->Set( "name", option );
			if ( !_edit->Load() ) {
				delete _edit;
				_edit = NULL;
				avatar->Send( "That user does not exist.\n\r" );
       		return;
       	}
		    _name = _edit->Get( "name" );
			buf << "You are now editing [{b" << _edit->Get( "name" ) << "{x]\n\r";
			avatar->Send( buf );
			return;
		}

	
	if ( command ) {
		avatar->Send( "That is an invalid # command. Try #commands\n\r" );
	}
}


string EditAvatarHandler::Prompt( Avatar * avatar ) {
	return _edit == NULL ? "Enter avatar: " : ">> ";
}

